home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
role
/
pinfocom_3_0.lha
/
Source
/
amiga_script.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-22
|
15KB
|
619 lines
/* amiga_script.c
*
* ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
* Copyright (C) 1987-1992 InfoTaskForce
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to the
* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Header: RCS/amiga_script.c,v 3.0 1992/10/21 16:56:19 pds Stab $
*/
#ifndef _AMIGA_GLOBAL_H
#include "amiga_global.h"
#endif /* !_AMIGA_GLOBAL_H */
/* ScriptWrite(const char *Buffer,int Width):
*
* Write a null-terminated string to the
* transcript file, adding a new-line
* character.
*/
Bool
ScriptWrite(const char *Buffer,const int Width)
{
/* Are we still to continue scripting? */
if(ScriptAborted)
return(FALSE);
else
{
if(Width)
{
/* Flush the current line buffer contents to the transcript
* file, close it if the action fails.
*/
if(!fwrite(Buffer,Width,1,ScriptFile))
{
scr_putmesg("Error writing to transcript file",TRUE);
ScriptAborted = TRUE;
return(FALSE);
}
}
if(!fwrite("\n",1,1,ScriptFile))
{
scr_putmesg("Error writing to transcript file",TRUE);
ScriptAborted = TRUE;
return(FALSE);
}
return(TRUE);
}
}
/* ScriptCreateGadgets():
*
* Create the gadgets for the printer control panel.
*/
struct Gadget *
ScriptCreateGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,const APTR VisualInfo,UWORD *Width,UWORD *Height,const struct Screen *Screen)
{
/* The gadget title labels. */
STATIC STRPTR GadgetLabels[] =
{
"Transcript output file or device",
"Transcript page width",
"Okay",
"Cancel",
"Select a file..."
};
/* A bunch of local variables. */
struct Gadget *Gadget;
struct NewGadget NewGadget;
WORD Counter = 0;
/* Zero the template. */
memset(&NewGadget,0,sizeof(struct NewGadget));
/* Create the root info. */
if(Gadget = CreateContext(GadgetList))
{
WORD ButtonWidth,
StringWidth,
MaxWidth,
Temp,
i;
/* Determine the longest string/integer gadget label. */
MaxWidth = 0;
for(i = SCRIPTGAD_PRINTER_STRING ; i <= SCRIPTGAD_PRINTER_WIDTH ; i++)
{
if((Temp = 2 * INTERWIDTH + TextLength((struct RastPort *)&Screen -> RastPort,GadgetLabels[i],strlen(GadgetLabels[i]))) > MaxWidth)
MaxWidth = Temp;
}
/* Store the longest label width. */
StringWidth = MaxWidth;
/* Determine the longest button gadget label. */
MaxWidth = 0;
for(i = SCRIPTGAD_PRINTER_ACCEPT ; i <= SCRIPTGAD_PRINTER_SELECT ; i++)
{
if((Temp = 2 * INTERWIDTH + TextLength((struct RastPort *)&Screen -> RastPort,GadgetLabels[i],strlen(GadgetLabels[i]))) > MaxWidth)
MaxWidth = Temp;
}
/* Store the longest label width. */
ButtonWidth = MaxWidth;
/* Are the three buttons in a row longer
* than the string/integer gadget? If so,
* adjust the string/integer gadget width.
*/
if(3 * ButtonWidth + 2 * INTERWIDTH > StringWidth)
StringWidth = 3 * ButtonWidth + 2 * INTERWIDTH;
/* Determine window size. */
*Width = Screen -> WBorLeft + INTERWIDTH + StringWidth + INTERWIDTH + Screen -> WBorRight;
*Height = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 * (2 * INTERHEIGHT + Screen -> Font -> ta_YSize) + 3 * (Screen -> Font -> ta_YSize + 6) + 2 * INTERHEIGHT + Screen -> WBorBottom;
/* Set up for gadget creation. */
NewGadget . ng_GadgetText = GadgetLabels[SCRIPTGAD_PRINTER_STRING];
NewGadget . ng_TextAttr = Screen -> Font;
NewGadget . ng_VisualInfo = VisualInfo;
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = PLACETEXT_ABOVE;
NewGadget . ng_LeftEdge = Screen -> WBorLeft + INTERWIDTH;
NewGadget . ng_TopEdge = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 * INTERHEIGHT + Screen -> Font -> ta_YSize;
NewGadget . ng_Width = StringWidth;
NewGadget . ng_Height = Screen -> Font -> ta_YSize + 6;
GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
GTST_MaxChars,255,
TAG_DONE);
NewGadget . ng_GadgetText = GadgetLabels[SCRIPTGAD_PRINTER_WIDTH];
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + NewGadget . ng_Height + 2 * INTERHEIGHT + Screen -> Font -> ta_YSize;
GadgetArray[Counter++] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,TAG_DONE);
NewGadget . ng_GadgetText = GadgetLabels[SCRIPTGAD_PRINTER_ACCEPT];
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_Flags = NULL;
NewGadget . ng_TopEdge = NewGadget . ng_TopEdge + NewGadget . ng_Height + INTERHEIGHT;
NewGadget . ng_Width = ButtonWidth;
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
NewGadget . ng_GadgetText = GadgetLabels[SCRIPTGAD_PRINTER_CANCEL];
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_LeftEdge = (*Width) - (Screen -> WBorLeft + INTERWIDTH + NewGadget . ng_Width);
GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
NewGadget . ng_GadgetText = GadgetLabels[SCRIPTGAD_PRINTER_SELECT];
NewGadget . ng_GadgetID = Counter;
NewGadget . ng_LeftEdge = ((*Width) - NewGadget . ng_Width) / 2;
GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
}
return(Gadget);
}
/* ScriptGetPrinterName(STRPTR PrinterName,int *PrinterWidth):
*
* Open the printer control panel.
*/
Bool
ScriptGetPrinterName(STRPTR PrinterName,int *PrinterWidth)
{
STATIC char FileName[MAX_FILENAME_LENGTH];
struct Gadget *GadgetArray[SCRIPTGAD_PRINTER_SELECT + 1],
*GadgetList;
struct Window *PrinterWindow;
UWORD Width,
Height;
char *Index;
Bool Result = FALSE;
/* Get the path part of the file name,
* check if ends in a null-character,
* if so, it's probably just a device name.
*/
if(Index = PathPart(PrinterName))
{
/* If it has a file name attached, copy it to the filename buffer. */
if(*Index)
strcpy(FileName,PrinterName);
else
{
int ExtensionLen,
NameLen,
i;
Bool GotIt = FALSE;
/* Use the story file name to start. */
strcpy(FileName,gflags . filenm);
/* Determine name length. */
NameLen = strlen(FileName);
/* Try to find a matching game
* file name extension.
*/
for(i = 0 ; !GotIt && StoryExtensions[i] ; i++)
{
/* Is the game file name long enough
* to hold an extension?
*/
if((ExtensionLen = strlen(StoryExtensions[i])) > NameLen)
{
/* Does the extension match? */
if(!Stricmp(&FileName[NameLen - ExtensionLen],StoryExtensions[i]))
{
/* Add new file name extension. */
strcpy(&FileName[NameLen - ExtensionLen],SCRIPT_EXT);
/* We're done now. */
GotIt = TRUE;
}
}
}
/* If we didn't succeed in adding
* a new file name extension, just
* attach the default.
*/
if(!GotIt)
{
/* Strip any existing extension. */
for(i = NameLen - 1 ; i >= 0 ; i--)
{
if(FileName[i] == '.')
{
FileName[i] = 0;
break;
}
}
/* Attach the default script
* file name extension.
*/
strcat(FileName,SCRIPT_EXT);
}
}
}
/* Create the gadgets for the window. */
if(ScriptCreateGadgets(&GadgetArray[0],&GadgetList,VisualInfo,&Width,&Height,Window -> WScreen))
{
/* Open the window. */
if(PrinterWindow = OpenWindowTags(NULL,
WA_Top, Window -> TopEdge + (Window -> Height - Height) / 2,
WA_Left, Window -> LeftEdge + (Window -> Width - Width) / 2,
WA_Title, "Save transcript file",
WA_Width, Width,
WA_Height, Height,
WA_IDCMP, IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW | STRINGIDCMP | BUTTONIDCMP,
WA_Activate, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_RMBTrap, TRUE,
WA_CustomScreen, Window -> WScreen,
TAG_DONE))
{
STATIC struct Requester BlockRequester;
struct IntuiMessage *Massage;
ULONG Class;
struct Gadget *Gadget;
Bool Terminated = FALSE;
STRPTR Buffer;
/* Add the gadgets and render them. */
AddGList(PrinterWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
RefreshGList(GadgetList,PrinterWindow,NULL,(UWORD)-1);
GT_RefreshWindow(PrinterWindow,NULL);
/* Set the string gadget (output file name). */
GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL,
GTST_String, PrinterName,
TAG_DONE);
/* Set the integer gadget (output file width). */
GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_WIDTH],PrinterWindow,NULL,
GTIN_Number, *PrinterWidth,
TAG_DONE);
/* Activate the file/device name gadget. */
ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL);
/* A handy shortcut. */
Buffer = GT_STRING(GadgetArray[SCRIPTGAD_PRINTER_STRING]);
/* Enter input loop. */
do
{
/* Wait for input. */
WaitPort(PrinterWindow -> UserPort);
/* Process all incoming messages. */
while(Massage = GT_GetIMsg(PrinterWindow -> UserPort))
{
/* Remember input class and gadget. */
Class = Massage -> Class;
Gadget = (struct Gadget *)Massage -> IAddress;
/* Return the input event message. */
GT_ReplyIMsg(Massage);
/* Which kind of message did we receive? */
switch(Class)
{
/* Activate a string gadget? */
case IDCMP_VANILLAKEY: ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL);
break;
/* Close the window? */
case IDCMP_CLOSEWINDOW: Terminated = TRUE;
break;
/* A button has been pressed? */
case IDCMP_GADGETUP: switch(Gadget -> GadgetID)
{
/* Activate the printer width gadget? */
case SCRIPTGAD_PRINTER_STRING:ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_WIDTH],PrinterWindow,NULL);
break;
/* Accept current settings. */
case SCRIPTGAD_PRINTER_ACCEPT:if(Buffer[0])
{
/* Copy the new printer output file/device name. */
strcpy(PrinterName,(char *)Buffer);
/* Quit the loop the next time. */
Terminated = Result = TRUE;
/* Get current printer width, don't make it too small. */
if((*PrinterWidth = GT_INTEGER(GadgetArray[SCRIPTGAD_PRINTER_WIDTH])) < MIN_PRINTER_COLUMNS)
*PrinterWidth = MIN_PRINTER_COLUMNS;
}
break;
/* Select a new output file. */
case SCRIPTGAD_PRINTER_SELECT:
/* Clear the requester. */
memset(&BlockRequester,0,sizeof(struct Requester));
/* Block window input. */
Request(&BlockRequester,PrinterWindow);
/* Set the window wait pointer. */
WaitPointer(PrinterWindow);
strcpy(TempBuffer,FileName);
/* Extract the path name. */
if(Index = PathPart(TempBuffer))
*Index = 0;
/* If no path name is given, supply the
* current directory.
*/
if(!TempBuffer[0])
{
/* Try to obtain the current directory name.
* If this fails, leave the path name empty.
*/
if(!GetCurrentDirName(TempBuffer,MAX_FILENAME_LENGTH))
TempBuffer[0] = 0;
}
/* Request the file name. */
if(AslRequestTags(GameFileRequest,
ASL_Window, PrinterWindow,
ASL_Dir, TempBuffer,
ASL_File, FilePart(FileName),
ASL_FuncFlags, FILF_SAVE,
ASL_Hail, "Select transcript file to save",
ASL_Pattern, "~(#?.info)",
TAG_DONE))
{
/* Did we get a file name? */
if(GameFileRequest -> rf_File[0])
{
/* Copy the drawer name. */
strcpy(TempBuffer,(char *)GameFileRequest -> rf_Dir);
/* Add the file name. */
if(AddPart(TempBuffer,GameFileRequest -> rf_File,MAX_FILENAME_LENGTH))
{
/* Update the file name string. */
GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL,
GTST_String,TempBuffer,
TAG_DONE);
/* Remember the file name. */
strcpy(FileName,TempBuffer);
}
}
}
ClearPointer(PrinterWindow);
EndRequest(&BlockRequester,PrinterWindow);
break;
/* Cancel the requester. */
case SCRIPTGAD_PRINTER_CANCEL:Terminated = TRUE;
break;
}
break;
}
if(Terminated)
break;
}
}
while(!Terminated);
/* Close the printer control window. */
CloseWindow(PrinterWindow);
}
/* Free the gadgets. */
FreeGadgets(GadgetList);
}
return(Result);
}
/* ScriptSplitLine(char *Line,int Len,const Bool ReturnPrompt):
*
* Split a hunk of text into neat little pieces.
*/
char *
ScriptSplitLine(char *Line,int Len,const Bool ReturnPrompt)
{
int Count,
Space;
/* Process & chop the text. */
do
{
/* Does the entire line fit? */
if(Len <= ScriptWidth)
{
if(ReturnPrompt)
return(Line);
else
ScriptWrite(Line,Count = Len);
}
else
{
/* Reset the counters. */
Space = Count = 0;
/* Determine number of
* characters to fit and
* the last space to use
* for text-wrapping.
*/
while(Count < Len && Count + 1 < ScriptWidth)
{
Count++;
/* Remember last space. */
if(Line[Count] == ' ')
Space = Count;
}
/* Return remainder. */
if(Count == Len)
{
if(ReturnPrompt)
return(Line);
else
{
if(Line[Count - 1] == ' ')
ScriptWrite(Line,Count - 1);
else
ScriptWrite(Line,Count);
}
}
else
{
/* Write the line. */
if(Line[Count - 1] == ' ')
{
if(!ScriptWrite(Line,Count - 1))
break;
}
else
{
if(!ScriptWrite(Line,Space))
break;
else
Count = Space + 1;
}
}
/* Move up. */
Line += Count;
}
/* Reduce remaining length. */
Len -= Count;
}
while(Len > 0);
/* Return blank line. */
return("");
}